const express = require('express');
const cors = require('cors');
const path = require('path');
const fs = require('fs-extra');
const XLSX = require('xlsx');

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.static(path.join(__dirname, '../dist')));

// 数据文件路径
const dataDir = path.join(__dirname, '../data');
const teachersFile = path.join(dataDir, 'teachers.json');
const examsFile = path.join(dataDir, 'exams.json');
const assignmentsFile = path.join(dataDir, 'assignments.json');

// 确保数据目录存在
fs.ensureDirSync(dataDir);

// 初始化数据文件
const initDataFiles = () => {
  if (!fs.existsSync(teachersFile)) {
    fs.writeJsonSync(teachersFile, []);
  }
  if (!fs.existsSync(examsFile)) {
    fs.writeJsonSync(examsFile, []);
  }
  if (!fs.existsSync(assignmentsFile)) {
    fs.writeJsonSync(assignmentsFile, []);
  }
};

initDataFiles();

// 获取下一个ID
const getNextId = (data) => {
  if (data.length === 0) return 1;
  return Math.max(...data.map(item => item.id || 0)) + 1;
};

// API路由

// 教师管理
app.get('/api/teachers', (req, res) => {
  try {
    const teachers = fs.readJsonSync(teachersFile);
    res.json(teachers);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/api/teachers', (req, res) => {
  try {
    const teachers = fs.readJsonSync(teachersFile);
    const newTeacher = {
      id: getNextId(teachers),
      ...req.body,
      lives_in_weishui: req.body.lives_in_weishui ? 1 : 0,
      created_at: new Date().toISOString()
    };
    
    // 检查工号是否重复
    if (teachers.some(t => t.employee_id === newTeacher.employee_id)) {
      return res.status(400).json({ error: '工号已存在' });
    }
    
    teachers.push(newTeacher);
    fs.writeJsonSync(teachersFile, teachers);
    res.json({ id: newTeacher.id, message: '教师添加成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.put('/api/teachers/:id', (req, res) => {
  try {
    const teachers = fs.readJsonSync(teachersFile);
    const index = teachers.findIndex(t => t.id === parseInt(req.params.id));
    
    if (index === -1) {
      return res.status(404).json({ error: '教师不存在' });
    }
    
    // 检查工号是否重复（排除当前教师）
    if (teachers.some(t => t.employee_id === req.body.employee_id && t.id !== parseInt(req.params.id))) {
      return res.status(400).json({ error: '工号已存在' });
    }
    
    teachers[index] = {
      ...teachers[index],
      ...req.body,
      lives_in_weishui: req.body.lives_in_weishui ? 1 : 0,
      id: parseInt(req.params.id)
    };
    
    fs.writeJsonSync(teachersFile, teachers);
    res.json({ message: '教师信息更新成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.delete('/api/teachers/:id', (req, res) => {
  try {
    const teachers = fs.readJsonSync(teachersFile);
    const filteredTeachers = teachers.filter(t => t.id !== parseInt(req.params.id));
    
    if (filteredTeachers.length === teachers.length) {
      return res.status(404).json({ error: '教师不存在' });
    }
    
    fs.writeJsonSync(teachersFile, filteredTeachers);
    res.json({ message: '教师删除成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 考试管理
app.get('/api/exams', (req, res) => {
  try {
    const exams = fs.readJsonSync(examsFile);
    res.json(exams);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/api/exams', (req, res) => {
  try {
    const exams = fs.readJsonSync(examsFile);
    const { name, exam_id, exam_time, student_count } = req.body;
    const supervisor_count = Math.floor(student_count / 20) + 1;
    
    // 检查考试编号是否重复
    if (exams.some(e => e.exam_id === exam_id)) {
      return res.status(400).json({ error: '考试编号已存在' });
    }
    
    const newExam = {
      id: getNextId(exams),
      name,
      exam_id,
      exam_time,
      student_count,
      supervisor_count,
      created_at: new Date().toISOString()
    };
    
    exams.push(newExam);
    fs.writeJsonSync(examsFile, exams);
    res.json({ id: newExam.id, supervisor_count, message: '考试添加成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.put('/api/exams/:id', (req, res) => {
  try {
    const exams = fs.readJsonSync(examsFile);
    const index = exams.findIndex(e => e.id === parseInt(req.params.id));
    
    if (index === -1) {
      return res.status(404).json({ error: '考试不存在' });
    }
    
    const { name, exam_id, exam_time, student_count } = req.body;
    const supervisor_count = Math.floor(student_count / 20) + 1;
    
    // 检查考试编号是否重复（排除当前考试）
    if (exams.some(e => e.exam_id === exam_id && e.id !== parseInt(req.params.id))) {
      return res.status(400).json({ error: '考试编号已存在' });
    }
    
    exams[index] = {
      ...exams[index],
      name,
      exam_id,
      exam_time,
      student_count,
      supervisor_count,
      id: parseInt(req.params.id)
    };
    
    fs.writeJsonSync(examsFile, exams);
    res.json({ supervisor_count, message: '考试信息更新成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.delete('/api/exams/:id', (req, res) => {
  try {
    const exams = fs.readJsonSync(examsFile);
    const filteredExams = exams.filter(e => e.id !== parseInt(req.params.id));
    
    if (filteredExams.length === exams.length) {
      return res.status(404).json({ error: '考试不存在' });
    }
    
    fs.writeJsonSync(examsFile, filteredExams);
    res.json({ message: '考试删除成功' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 排考算法
app.post('/api/schedule', (req, res) => {
  try {
    const teachers = fs.readJsonSync(teachersFile);
    const exams = fs.readJsonSync(examsFile);
    
    if (teachers.length === 0 || exams.length === 0) {
      return res.status(400).json({ error: '请先添加教师和考试信息' });
    }
    
    const result = scheduleExams(teachers, exams);
    
    // 保存排考结果
    const assignments = [];
    result.assignments.forEach(assignment => {
      assignment.teachers.forEach(teacherId => {
        assignments.push({
          id: assignments.length + 1,
          exam_id: assignment.examId,
          teacher_id: teacherId,
          assignment_date: new Date().toISOString()
        });
      });
    });
    
    fs.writeJsonSync(assignmentsFile, assignments);
    
    res.json({
      assignments: result.assignments,
      stats: result.stats,
      message: '排考完成'
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 获取排考结果
app.get('/api/assignments', (req, res) => {
  try {
    const assignments = fs.readJsonSync(assignmentsFile);
    const teachers = fs.readJsonSync(teachersFile);
    const exams = fs.readJsonSync(examsFile);
    
    const result = assignments.map(assignment => {
      const exam = exams.find(e => e.id === assignment.exam_id);
      const teacher = teachers.find(t => t.id === assignment.teacher_id);
      
      return {
        id: assignment.id,
        exam_name: exam?.name || '',
        exam_id: exam?.exam_id || '',
        exam_time: exam?.exam_time || '',
        teacher_name: teacher?.name || '',
        employee_id: teacher?.employee_id || '',
        lives_in_weishui: teacher?.lives_in_weishui || 0
      };
    });
    
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 导出Excel
app.get('/api/export', (req, res) => {
  try {
    const assignments = fs.readJsonSync(assignmentsFile);
    const teachers = fs.readJsonSync(teachersFile);
    const exams = fs.readJsonSync(examsFile);
    
    const data = assignments.map(assignment => {
      const exam = exams.find(e => e.id === assignment.exam_id);
      const teacher = teachers.find(t => t.id === assignment.teacher_id);
      
      return {
        '考试名称': exam?.name || '',
        '考试编号': exam?.exam_id || '',
        '考试时间': exam?.exam_time || '',
        '考试人数': exam?.student_count || 0,
        '监考人数': exam?.supervisor_count || 0,
        '监考教师': teacher?.name || '',
        '工号': teacher?.employee_id || '',
        '是否在渭水居住': teacher?.lives_in_weishui ? '是' : '否'
      };
    });
    
    const ws = XLSX.utils.json_to_sheet(data);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, '排考结果');
    
    const buffer = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' });
    
    res.setHeader('Content-Disposition', 'attachment; filename=exam_schedule.xlsx');
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.send(buffer);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 排考算法实现
function scheduleExams(teachers, exams) {
  const assignments = [];
  const teacherStats = {};
  
  // 初始化教师统计
  teachers.forEach(teacher => {
    teacherStats[teacher.id] = {
      assignmentCount: 0,
      tripCount: 0,
      employeeId: parseInt(teacher.employee_id)
    };
  });
  
  // 按考试时间排序
  exams.sort((a, b) => new Date(a.exam_time) - new Date(b.exam_time));
  
  exams.forEach(exam => {
    const availableTeachers = teachers.filter(teacher => {
      return isTeacherAvailable(teacher, exam.exam_time);
    });
    
    // 按工号和当前监考次数排序选择教师
    availableTeachers.sort((a, b) => {
      const statA = teacherStats[a.id];
      const statB = teacherStats[b.id];
      
      // 先按监考次数升序，再按工号降序
      if (statA.assignmentCount !== statB.assignmentCount) {
        return statA.assignmentCount - statB.assignmentCount;
      }
      return statB.employeeId - statA.employeeId;
    });
    
    const selectedTeachers = availableTeachers.slice(0, exam.supervisor_count);
    
    if (selectedTeachers.length < exam.supervisor_count) {
      throw new Error(`考试 ${exam.name} 可用教师不足，需要${exam.supervisor_count}人，实际可用${selectedTeachers.length}人`);
    }
    
    // 更新统计信息
    selectedTeachers.forEach(teacher => {
      teacherStats[teacher.id].assignmentCount++;
      // 简化处理：每次监考算一次出行
      teacherStats[teacher.id].tripCount++;
    });
    
    assignments.push({
      examId: exam.id,
      examName: exam.name,
      examTime: exam.exam_time,
      teachers: selectedTeachers.map(t => t.id),
      teacherNames: selectedTeachers.map(t => t.name)
    });
  });
  
  // 计算目标函数
  const assignmentCounts = Object.values(teacherStats).map(s => s.assignmentCount);
  const maxAssignments = assignmentCounts.length > 0 ? Math.max(...assignmentCounts) : 0;
  const minAssignments = assignmentCounts.length > 0 ? Math.min(...assignmentCounts) : 0;
  const totalTrips = Object.values(teacherStats).reduce((sum, s) => sum + s.tripCount, 0);
  
  return {
    assignments,
    stats: {
      maxAssignments,
      minAssignments,
      assignmentDifference: maxAssignments - minAssignments,
      totalTrips,
      objectiveValue: totalTrips + (maxAssignments - minAssignments) * 10
    }
  };
}

function isTeacherAvailable(teacher, examTime) {
  // 简化的可用性检查
  // 实际实现中需要解析上课时间和不想监考时间
  if (teacher.unavailable_time) {
    const unavailableTimes = teacher.unavailable_time.split(',');
    const examDate = new Date(examTime);
    const examDay = examDate.getDay(); // 0=周日, 1=周一, ...
    
    // 这里应该有更复杂的时间冲突检查逻辑
    // 暂时简化处理
  }
  
  return true;
}

// 服务静态文件
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '../dist/index.html'));
});

app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});
